
function print(x)
{
    document.writeln(x + "<br/>");
}

var apples = 0;

print(apples);
function test1()
{
    apples = apples + 2;
    print("in test1(): " + apples);
}

function test2()
{
    test1();
    apples = apples + 3;
    print("in test2(): " + apples);
}

test2();
print(apples);

/********************************************************************************
 Creating an object
*********************************************************************************/
function people(name, age)
{
	this.name = name;
	this.age = age;
	
	// Using a method inside of an object
	this.yearsToRetirement = yearsUntilRetirement; // Do not use parenthesis.
}

function yearsUntilRetirement()
{
	var years = 65 - this.age;
	return years;
}

var brian = new people("brian", 25);

print(brian.name + " is " + brian.age);

// Using object initializers
var obj_init = { name : "bob", age : 35 };

print(obj_init.name + " is " + obj_init.age);

// Test method
print("brian will retire in " + brian.yearsToRetirement() + " years");

/********************************************************************************
Arrays
*********************************************************************************/
var people = new Array("brian", "david", "peter", "john");
print(people[2] + " is after " + people[1]);
print(people.length);


var dudes = new Array("brian", "david");
var chicks = new Array("lisa", "erin");
var allPeople = dudes.concat(chicks);
allPeople.reverse();
allPeople.push("tom");
allPeople.sort();
var blah = allPeople.join(); // converts array to string separated by commas
print(blah);

// Associative Arrays
var bucky = new Array();
bucky["food"] = "pizza";
bucky["drink"] = "coke";
print("buck's favorite food is " + bucky["food"]);

/********************************************************************************
Classes and Methods 
*********************************************************************************/
// #1
function Calc(){
	this.multiply = function(v1,v2){
		return v1*v2;
	}
}
var c = new Calc();
print(c.multiply(11,2));

// #2

function Calc2(){
	// methods and properties go inside here
	this.blah = 5;
	this.multiply = mult; // dont use parenthesis here
}

function mult(v1,v2){
	return v1*v2;
}


var c2 = new Calc2();
print ("test c2");
print(c2.multiply(10,3));

// #3
function Calc3(){

}

Calc3.prototype.multiply = function(v1,v2){
	return v1*v2;
}
var calc3 = new Calc3();
print(calc3.multiply(20,5));

// #4 Using JSON
 var apple = {
 type: "macintosh",
 color: "red",
 getInfo: function () {
	 return this.color + ' ' + this.type + ' apple';
	}
 }

 apple.color = "reddish";
 print(apple.getInfo());

/********************************************************************************************************
Passing by Value versus Passing by Reference
*********************************************************************************************************/
// When passing a primitive type (string or number), the value is passed by value.
function my_function(x)
{
	// x is 4
	x = 5;
    // x is now 5
}

// When passing in an object, it is passed by reference.
function my_object()
{
    this.value = 5;
}

var o = new my_object();
print(o.value); // o.value is 5
function obj_change(x)
{
    x.value = 6;
}
obj_change(o);
print(o.value); // o.value is now 6

// What happens when you pass in a method of an object?
my_object.prototype.add = function()
{
    this.value++;
}

print("value of o is = " + o.value);
o.add();
print("value of o after add() is = " + o.value);

function meth_call(func)
{
    func();
}
meth_call(o.add);   // The problem is the use of the "this" keyword. The content is lost when passing by function. The "this"
// now refers to the context of the object making the call. For stand alone functions, this is the window object.
// For functions called from an event, that would be the event object.
print("value of o after calling meth_call(o.add) is still " + o.value);

// In order to do this, you must pass the function and object.
function meth_call2(func, obj)
{
    func.call(obj);
}
meth_call2(o.add, o);
print("value of o after calling meth_call2(o.add,o) is now " + o.value);

// Or Alternatively, you can do the following

function meth_call3(obj)
{
    obj.add();
}

meth_call3(o);
print("value of o after calling meth_call3(o.add,o) is now " + o.value);

